package commands;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.pircbotx.Channel;
import org.pircbotx.User;
import org.pircbotx.hooks.events.WhoisEvent;

import backend.Bot;

public class WhoisStatsCommand extends Command
{

	Map<String,Integer> stats;
	ArrayList<String> loyalUsers;
	String mostIdle;
	long idleTime;

	@Override
	protected void initialize()
	{
		setAccessLevel(LEVEL_ELEVATED);
		setName("WhoisStatsCommand");
		addAlias("whoisstats");
		addAlias("whois-stats");
		addAlias("whois");
		setHelpText("Gives some miscellaneous statistics on the channels that everyone else is currently in.");
		stats = new HashMap<String,Integer>();
		loyalUsers = new ArrayList<String>();
	}
	
@Override
	public void execute(Bot bot, Channel chan, User user, String message)
	{
		stats.clear();
		loyalUsers.clear();
		for(User u:chan.getUsers())
		{
			bot.sendRawLine("WHOIS "+u.getNick());
			try
			{
				bot.waitFor(WhoisEvent.class);
			} catch (InterruptedException e)
			{
				e.printStackTrace();
			}
		}
		
		// remove stuff we don't want
//		stats.remove(chan.getName());
		
		Map<String, Integer> sortedStats = sortByValues(stats);
		
		String sharedChans = "Channels "+chan.getName()+" users have in common: ";
		String delim = "";
		for(String c:sortedStats.keySet())
		{
			if(c.equals(chan.getName()))
				continue;
			if(1 == stats.get(c))
				break; // no need to continue, there are no more shared chans
			sharedChans += delim + c + "("+stats.get(c)+")";
			delim = ", ";
		}
		
		String loyalMsg = loyalUsers.size() + " users are loyal to this channel only (haven't joined any other channel): ";
		delim = "";
		for(String u:loyalUsers)
		{
			loyalMsg += delim + u;
			delim = ", ";
		}
		
		String mostIdleMsg = mostIdle + " is the most idle user in the channel with an idle time of ";
		long hours = idleTime / 3600; idleTime %= 3600;
		long minutes = idleTime / 60; idleTime %= 60;
		long seconds = idleTime;
		mostIdleMsg += hours + " hours, " + minutes + " minutes, " + seconds + " seconds.";
		
		passMessage(bot, chan, user, sharedChans);
		passMessage(bot, chan, user, loyalMsg);
	}
	
	@Override
	public void onWhois(WhoisEvent<Bot> event) throws Exception
	{
		super.onWhois(event);
		if(event.getNick().equals(event.getBot().getNick()))
			return;
		List<String> list = event.getChannels();
		for(String chan:list)
		{
			chan = chan.substring(chan.indexOf('#'));
			if(stats.containsKey(chan))
			{
				stats.put(chan,stats.get(chan)+1);
			}
			else
			{
				stats.put(chan,1);
			}
		}
		if(list.size()==1)
			loyalUsers.add(event.getNick());
		
		if(event.getIdleSeconds() > idleTime)
		{
			idleTime = event.getIdleSeconds();
			mostIdle = event.getNick();
		}
	}

	public static <K, V extends Comparable<V>> Map<K, V> sortByValues(final Map<K, V> map) {
	    Comparator<K> valueComparator =  new Comparator<K>() {
	        public int compare(K k1, K k2) {
	            int compare = map.get(k2).compareTo(map.get(k1));
	            if (compare == 0) return 1;
	            else return compare;
	        }
	    };
	    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
	    sortedByValues.putAll(map);
	    return sortedByValues;
	}
	
}
